return -EINVAL;
if ( a.domid == DOMID_SELF )
+ {
d = rcu_lock_current_domain();
- else {
- d = rcu_lock_domain_by_id(a.domid);
- if ( d == NULL )
+ }
+ else
+ {
+ if ( (d = rcu_lock_domain_by_id(a.domid)) == NULL )
return -ESRCH;
- if ( !IS_PRIV_FOR(current->domain, d) ) {
+ if ( !IS_PRIV_FOR(current->domain, d) )
+ {
rc = -EPERM;
goto param_fail;
}
info->foreign = rcu_lock_domain(dom_xen);
break;
default:
- e = rcu_lock_domain_by_id(domid);
- if ( e == NULL )
+ if ( (e = rcu_lock_domain_by_id(domid)) == NULL )
{
MEM_LOG("Unknown domain '%u'", domid);
okay = 0;
break;
}
- if (!IS_PRIV_FOR(d, e)) {
+ if ( !IS_PRIV_FOR(d, e) )
+ {
MEM_LOG("Cannot set foreign dom");
okay = 0;
rcu_unlock_domain(e);
return -EFAULT;
if ( xatp.domid == DOMID_SELF )
+ {
d = rcu_lock_current_domain();
- else {
- d = rcu_lock_domain_by_id(xatp.domid);
- if ( d == NULL )
+ }
+ else
+ {
+ if ( (d = rcu_lock_domain_by_id(xatp.domid)) == NULL )
return -ESRCH;
- if ( !IS_PRIV_FOR(current->domain, d) ) {
+ if ( !IS_PRIV_FOR(current->domain, d) )
+ {
rcu_unlock_domain(d);
return -EPERM;
}
return -EINVAL;
if ( fmap.domid == DOMID_SELF )
+ {
d = rcu_lock_current_domain();
- else {
- d = rcu_lock_domain_by_id(fmap.domid);
- if ( d == NULL )
+ }
+ else
+ {
+ if ( (d = rcu_lock_domain_by_id(fmap.domid)) == NULL )
return -ESRCH;
- if ( !IS_PRIV_FOR(current->domain, d) ) {
+ if ( !IS_PRIV_FOR(current->domain, d) )
+ {
rcu_unlock_domain(d);
return -EPERM;
}
if ( (v = d->vcpu[i]) != NULL )
free_vcpu_struct(v);
- if (d->target)
+ if ( d->target != NULL )
put_domain(d->target);
free_domain(d);
struct xen_domctl curop, *op = &curop;
static DEFINE_SPINLOCK(domctl_lock);
+ if ( !IS_PRIV(current->domain) )
+ return -EPERM;
+
if ( copy_from_guest(op, u_domctl, 1) )
return -EFAULT;
if ( d == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto svc_out;
-
ret = xsm_setvcpucontext(d);
if ( ret )
goto svc_out;
ret = -ESRCH;
if ( d != NULL )
{
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto pausedomain_out;
-
ret = xsm_pausedomain(d);
if ( ret )
goto pausedomain_out;
if ( d == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto unpausedomain_out;
-
ret = xsm_unpausedomain(d);
if ( ret )
- goto unpausedomain_out;
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
domain_unpause_by_systemcontroller(d);
- ret = 0;
-unpausedomain_out:
rcu_unlock_domain(d);
+ ret = 0;
}
break;
if ( d == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto resumedomain_out;
-
ret = xsm_resumedomain(d);
if ( ret )
- goto resumedomain_out;
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
domain_resume(d);
- ret = 0;
-resumedomain_out:
rcu_unlock_domain(d);
+ ret = 0;
}
break;
static domid_t rover = 0;
unsigned int domcr_flags;
- ret = -EPERM;
- if ( !IS_PRIV(current->domain) )
- break;
-
ret = -EINVAL;
if ( supervisor_mode_kernel ||
(op->u.createdomain.flags &
if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto maxvcpu_out2;
-
ret = xsm_max_vcpus(d);
if ( ret )
- goto maxvcpu_out2;
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
/* Needed, for example, to ensure writable p.t. state is synced. */
domain_pause(d);
maxvcpu_out:
domain_unpause(d);
- maxvcpu_out2:
rcu_unlock_domain(d);
}
break;
ret = -ESRCH;
if ( d != NULL )
{
- ret = -EPERM;
- if ( IS_PRIV_FOR(current->domain, d) )
- ret = xsm_destroydomain(d) ? : domain_kill(d);
+ ret = xsm_destroydomain(d) ? : domain_kill(d);
rcu_unlock_domain(d);
}
}
if ( d == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto vcpuaffinity_out;
-
ret = xsm_vcpuaffinity(op->cmd, d);
if ( ret )
goto vcpuaffinity_out;
if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto scheduler_op_out;
-
ret = xsm_scheduler(d);
if ( ret )
goto scheduler_op_out;
rcu_read_lock(&domlist_read_lock);
for_each_domain ( d )
- if ( d->domain_id >= dom && IS_PRIV_FOR(current->domain, d))
+ if ( d->domain_id >= dom )
break;
if ( d == NULL )
if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto getvcpucontext_out;
-
ret = xsm_getvcpucontext(d);
if ( ret )
goto getvcpucontext_out;
if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto getvcpuinfo_out;
-
ret = xsm_getvcpuinfo(d);
if ( ret )
goto getvcpuinfo_out;
if ( d == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto max_mem_out;
-
ret = xsm_setdomainmaxmem(d);
if ( ret )
goto max_mem_out;
d->max_pages = new_max;
ret = 0;
}
- else
- printk("new max %ld, tot pages %d\n", new_max, d->tot_pages);
spin_unlock(&d->page_alloc_lock);
max_mem_out:
if ( d == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto setdomainhandle_out;
-
ret = xsm_setdomainhandle(d);
if ( ret )
- goto setdomainhandle_out;
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
memcpy(d->handle, op->u.setdomainhandle.handle,
sizeof(xen_domain_handle_t));
- ret = 0;
-setdomainhandle_out:
rcu_unlock_domain(d);
+ ret = 0;
}
break;
if ( d == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto setdebugging_out;
-
ret = xsm_setdebugging(d);
if ( ret )
- goto setdebugging_out;
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
domain_pause(d);
d->debugger_attached = !!op->u.setdebugging.enable;
domain_unpause(d); /* causes guest to latch new status */
- ret = 0;
-setdebugging_out:
rcu_unlock_domain(d);
+ ret = 0;
}
break;
if ( d == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto irq_permission_out;
-
ret = xsm_irq_permission(d, pirq, op->u.irq_permission.allow_access);
if ( ret )
goto irq_permission_out;
if ( d == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto iomem_permission_out;
-
ret = xsm_iomem_permission(d, mfn, op->u.iomem_permission.allow_access);
if ( ret )
goto iomem_permission_out;
if ( d == NULL )
break;
- ret = -EPERM;
- if ( !IS_PRIV_FOR(current->domain, d) )
- goto settimeoffset_out;
-
ret = xsm_domain_settime(d);
if ( ret )
- goto settimeoffset_out;
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds;
-
- ret = 0;
-settimeoffset_out:
rcu_unlock_domain(d);
+ ret = 0;
}
break;
if ( d == NULL )
break;
- ret = -EPERM;
- if (!IS_PRIV_FOR(current->domain, d))
- goto set_target_out;
-
ret = -ESRCH;
e = get_domain_by_id(op->u.set_target.target);
if ( e == NULL )
goto set_target_out;
- if ( d == e ) {
- ret = -EINVAL;
- put_domain(e);
- goto set_target_out;
- }
-
- if (!IS_PRIV_FOR(current->domain, e)) {
- ret = -EPERM;
+ ret = -EINVAL;
+ if ( (d == e) || (d->target != NULL) )
+ {
put_domain(e);
goto set_target_out;
}
+ /* Hold reference on @e until we destroy @d. */
d->target = e;
- /* and we keep the reference on e, released when destroying d */
+
ret = 0;
-set_target_out:
+ set_target_out:
rcu_unlock_domain(d);
}
break;
long rc;
if ( dom == DOMID_SELF )
- d = current->domain;
- else {
+ {
+ d = rcu_lock_current_domain();
+ }
+ else
+ {
if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
return -ESRCH;
- if ( !IS_PRIV_FOR(current->domain, d) ) {
- rc = -EPERM;
- goto out2;
+ if ( !IS_PRIV_FOR(current->domain, d) )
+ {
+ rcu_unlock_domain(d);
+ return -EPERM;
}
}
out:
spin_unlock(&d->evtchn_lock);
-
- out2:
rcu_unlock_domain(d);
return rc;
ERROR_EXIT_DOM(-EINVAL, rd);
rchn = evtchn_from_port(rd, rport);
if ( (rchn->state != ECS_UNBOUND) ||
- (rchn->u.unbound.remote_domid != ld->domain_id && !IS_PRIV_FOR(ld, rd)))
+ (rchn->u.unbound.remote_domid != ld->domain_id) )
ERROR_EXIT_DOM(-EINVAL, rd);
rc = xsm_evtchn_interdomain(ld, lchn, rd, rchn);
long rc = 0;
if ( dom == DOMID_SELF )
- d = current->domain;
- else {
+ {
+ d = rcu_lock_current_domain();
+ }
+ else
+ {
if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
return -ESRCH;
- if ( !IS_PRIV_FOR(current->domain, d) ) {
- rc = -EPERM;
- goto out2;
+ if ( !IS_PRIV_FOR(current->domain, d) )
+ {
+ rcu_unlock_domain(d);
+ return -EPERM;
}
}
out:
spin_unlock(&d->evtchn_lock);
- out2:
rcu_unlock_domain(d);
+
return rc;
}
out:
spin_unlock(&d->evtchn_lock);
+
return rc;
}
{
domid_t dom = r->dom;
struct domain *d;
- int i;
- int rc;
+ int i, rc;
if ( dom == DOMID_SELF )
- d = current->domain;
- else {
+ {
+ d = rcu_lock_current_domain();
+ }
+ else
+ {
if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
return -ESRCH;
- if ( !IS_PRIV_FOR(current->domain, d) ) {
+ if ( !IS_PRIV_FOR(current->domain, d) )
+ {
rc = -EPERM;
goto out;
}
(void)__evtchn_close(d, i);
rc = 0;
+
out:
rcu_unlock_domain(d);
" per domain.\n",
max_nr_grant_frames);
op.status = GNTST_general_error;
- goto out;
+ goto out1;
}
dom = op.dom;
if ( dom == DOMID_SELF )
{
- d = current->domain;
+ d = rcu_lock_current_domain();
}
- else {
+ else
+ {
if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
{
gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
op.status = GNTST_bad_domain;
- goto out;
+ goto out1;
}
- if ( unlikely(!IS_PRIV_FOR(current->domain, d)) ) {
+
+ if ( unlikely(!IS_PRIV_FOR(current->domain, d)) )
+ {
op.status = GNTST_permission_denied;
- goto setup_unlock_out2;
+ goto out2;
}
}
if ( xsm_grant_setup(current->domain, d) )
{
- rcu_unlock_domain(d);
op.status = GNTST_permission_denied;
- goto out;
+ goto out2;
}
spin_lock(&d->grant_table->lock);
nr_grant_frames(d->grant_table),
max_nr_grant_frames);
op.status = GNTST_general_error;
- goto setup_unlock_out;
+ goto out3;
}
op.status = GNTST_okay;
(void)copy_to_guest_offset(op.frame_list, i, &gmfn, 1);
}
- setup_unlock_out:
+ out3:
spin_unlock(&d->grant_table->lock);
-
- setup_unlock_out2:
+ out2:
rcu_unlock_domain(d);
-
- out:
+ out1:
if ( unlikely(copy_to_guest(uop, &op, 1)) )
return -EFAULT;
dom = op.dom;
if ( dom == DOMID_SELF )
{
- d = current->domain;
+ d = rcu_lock_current_domain();
}
- else {
+ else
+ {
if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
{
gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
op.status = GNTST_bad_domain;
goto query_out;
}
- if ( unlikely(!IS_PRIV_FOR(current->domain, d)) ) {
+
+ if ( unlikely(!IS_PRIV_FOR(current->domain, d)) )
+ {
op.status = GNTST_permission_denied;
goto query_out_unlock;
}
return -EFAULT;
if ( op.domid == DOMID_SELF )
- d = current->domain;
- else {
- d = rcu_lock_domain_by_id(op.domid);
- if ( d == NULL )
+ {
+ d = rcu_lock_current_domain();
+ }
+ else
+ {
+ if ( (d = rcu_lock_domain_by_id(op.domid)) == NULL )
return -ESRCH;
- if ( !IS_PRIV_FOR(current->domain, d) ) {
+ if ( !IS_PRIV_FOR(current->domain, d) )
+ {
rcu_unlock_domain(d);
return -EPERM;
}
}
if ( likely(reservation.domid == DOMID_SELF) )
- d = current->domain;
- else {
- d = rcu_lock_domain_by_id(reservation.domid);
- if ( d == NULL)
+ {
+ d = rcu_lock_current_domain();
+ }
+ else
+ {
+ if ( (d = rcu_lock_domain_by_id(reservation.domid)) == NULL )
return start_extent;
- if ( !IS_PRIV_FOR(current->domain, d) ) {
+ if ( !IS_PRIV_FOR(current->domain, d) )
+ {
rcu_unlock_domain(d);
return start_extent;
}
rc = xsm_memory_adjust_reservation(current->domain, d);
if ( rc )
{
- if ( reservation.domid != DOMID_SELF )
- rcu_unlock_domain(d);
+ rcu_unlock_domain(d);
return rc;
}
break;
}
- if ( unlikely(reservation.domid != DOMID_SELF) )
- rcu_unlock_domain(d);
+ rcu_unlock_domain(d);
rc = args.nr_done;
return -EFAULT;
if ( likely(domid == DOMID_SELF) )
- d = current->domain;
- else {
- d = rcu_lock_domain_by_id(domid);
- if ( d == NULL )
+ {
+ d = rcu_lock_current_domain();
+ }
+ else
+ {
+ if ( (d = rcu_lock_domain_by_id(domid)) == NULL )
return -ESRCH;
- if ( !IS_PRIV_FOR(current->domain, d) ) {
+ if ( !IS_PRIV_FOR(current->domain, d) )
+ {
rcu_unlock_domain(d);
return -EPERM;
}
rc = xsm_memory_stat_reservation(current->domain, d);
if ( rc )
{
- if ( domid != DOMID_SELF )
- rcu_unlock_domain(d);
+ rcu_unlock_domain(d);
return rc;
}
break;
}
- if ( unlikely(domid != DOMID_SELF) )
- rcu_unlock_domain(d);
+ rcu_unlock_domain(d);
break;